package org.easiermock;

import org.easiermock.invocationhandlers.DoNothingInvocationHandler;
import org.easiermock.testmocks.RealInterface;
import org.junit.Assert;
import org.junit.Test;

public class CreateConcreteInstanceTest {

	@Test
	public void testCreateConcreteInterface() {
		RealInterface obj = EasierMock.createConcreteInstance(RealInterface.class, null, null);
		try { 
			obj.method1();
			Assert.fail("Expected exception");
		} catch (UnsupportedOperationException e) {
			// Expected exception
		}
	}

	@Test
	public void testCreateConcreteAbstractWithDefaultInvocationHandler() {
		final int RETURN_VALUE = 1977;
		RealInterface obj = EasierMock.createConcreteInstance(
				TestAbstract.class, 
				new Class<?>[] { Integer.TYPE }, new Object[] {RETURN_VALUE});

		Assert.assertEquals(RETURN_VALUE, obj.method1());
		try {
			obj.method2();
			Assert.fail("Expected exception");
		} catch (UnsupportedOperationException e) {
			// Expected exception
		}
	}

	@Test
	public void testCreateConcreteAbstractWithInvocationHandler() {
		final int RETURN_VALUE = 1977;
		RealInterface obj = EasierMock.createConcreteInstance(
				TestAbstract.class, 
				DoNothingInvocationHandler.INSTANCE,
				new Class<?>[] { Integer.TYPE }, new Object[] {RETURN_VALUE});

		Assert.assertEquals(RETURN_VALUE, obj.method1());
		obj.method2();
		Assert.assertEquals(0.0f, obj.method3(), 0.0f);
	}

	static abstract class TestAbstract implements RealInterface {
		private int returnValue;
		
		public TestAbstract(int returnValue) {
			this.returnValue = returnValue;
		}
		
		public int method1() {
			return returnValue;
		}
	}
}
